import threading
import time
import logging
from typing import Callable, List, Any
from .exceptions import InvalidMessageFormat

logger = logging.getLogger(__name__)

class BatchProcessor:
    """批量消息处理器（参考XWebSnap.c的批量打包机制）"""
    def __init__(
        self,
        max_size: int = 50,        # 最大批量处理条数（匹配服务端XWebSnap.c的BATCH_SIZE）
        timeout: float = 0.1,      # 超时时间（秒）
        callback: Callable[[List[Any]], None] = None
    ):
        self.max_size = max_size
        self.timeout = timeout
        self.callback = callback
        
        # 线程安全数据结构
        self._buffer = []
        self._lock = threading.Lock()
        self._timer: threading.Timer = None
        self._running = True
        
        # 启动后台刷新线程（参考XWebSnap.c的定时推送机制）
        self._start_flush_thread()

    def add(self, data: Any):
        """添加单条数据到缓冲区"""
        with self._lock:
            if not self._running:
                raise RuntimeError("处理器已停止")
                
            self._buffer.append(data)
            
            # 达到批量大小时立即触发处理
            if len(self._buffer) >= self.max_size:
                self._flush()

    def _start_flush_thread(self):
        """启动定时刷新线程"""
        def flush_loop():
            while self._running:
                time.sleep(self.timeout)
                with self._lock:
                    if self._buffer:
                        self._flush()
                        
        self._flush_thread = threading.Thread(
            target=flush_loop,
            daemon=True,
            name="BatchProcessor-FlushThread"
        )
        self._flush_thread.start()

    def _flush(self):
        """处理当前缓冲区数据"""
        try:
            if not self._buffer:
                return
                
            # 复制当前缓冲区并清空
            batch = self._buffer.copy()
            self._buffer.clear()
            
            # 执行回调处理
            if self.callback:
                self._safe_callback(batch)
        except Exception as e:
            logger.error(f"批量处理失败: {str(e)}")
            raise

    def _safe_callback(self, batch: List[Any]):
        """安全执行回调（带异常捕获）"""
        try:
            self.callback(batch)
        except InvalidMessageFormat as e:
            logger.error(f"无效的消息格式: {e.raw_data}")
        except Exception as e:
            logger.error(f"回调处理异常: {str(e)}")

    def stop(self):
        """停止处理器并刷新剩余数据"""
        with self._lock:
            self._running = False
            if self._buffer:
                self._flush()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.stop()

    @property
    def pending_count(self) -> int:
        """当前待处理数据量"""
        with self._lock:
            return len(self._buffer) 